/*
 * inputs:
 * 	KEY0		reset
 * 	KEY1		x2 the speed of shifting
 * 	KEY2		/2 the speed of shifting
 * 	SW[0]		enables shifting to the right
 * 	SW[1]		enables shifting to the left; SW[0] overrides SW[1]
 * 	SW[2]		shifts additional 1's into the HEX displays and LEDR
 * 	SW[3]		shifts additional 0's into the HEX displays and LEDR
 *
 * outputs:
 * 	LEDR		shifting lights
 * 	HEX7-0	shifting pattern
 * 	LEDG		shifting speed (from 0 to 9)
*/
module lab1_part1 (	CLOCK_50, KEY, SW, HEX3, HEX2, HEX1, HEX0, LEDR, LEDG);
			
	// DE2 Pin assignments
	input 		  CLOCK_50;
	input  [2:0]  KEY;
	input  [17:0] SW; 
	output [6:0]  HEX3, HEX2, HEX1, HEX0;
	output [17:0] LEDR;
	output [7:0]  LEDG;
	
	// Registers
	reg [9:0]  pattern10 = 10'b1;
	reg [19:0] pattern20 = 20'b1;
	reg [25:0] counter = 26'b0;
	reg [25:0] counter_mask = 26'h800000;
	
	// Wire
	wire CLOCK;
	wire resetn;
	wire doublespeed;
	wire halfspeed;
	wire shift0;
	wire shift1;
	wire shiftleft;
	wire shiftright;
	wire [19:0]countealias; 
	
	// Static Assigmnents
	assign LEDR[9:0] = pattern10[9:0];
	assign CLOCK = |(counter & counter_mask);
	assign LEDR[17] = CLOCK;
	assign LEDG[7:0] = counter_mask[25:18];
	
	// Aliases
	assign resetn      = KEY[0];
	assign doublespeed = KEY[1];
	assign halfspeed   = KEY[2];
	assign shiftright = SW[0];
	assign shiftleft  = SW[1];
	assign shift1     = SW[2];
	assign shift0     = SW[3];
	
	assign HEX3[0] = ~pattern20[19];
	assign HEX3[1] = ~pattern20[18];
	assign HEX3[6] = ~pattern20[17];
	assign HEX3[4] = ~pattern20[16];
	assign HEX3[3] = ~pattern20[15];
	assign HEX3[2] = 1'b1;
	assign HEX3[5] = 1'b1;
	
	assign HEX2[3] = ~pattern20[14];
	assign HEX2[2] = ~pattern20[13];
	assign HEX2[6] = ~pattern20[12];
	assign HEX2[5] = ~pattern20[11];
	assign HEX2[0] = ~pattern20[10];
	assign HEX2[1] = 1'b1;
	assign HEX2[4] = 1'b1;
	
	assign HEX1[0] = ~pattern20[9];
	assign HEX1[1] = ~pattern20[8];
	assign HEX1[6] = ~pattern20[7];
	assign HEX1[4] = ~pattern20[6];
	assign HEX1[3] = ~pattern20[5];
	assign HEX1[2] = 1'b1;
	assign HEX1[5] = 1'b1;
	
	assign HEX0[3] = ~pattern20[4];
	assign HEX0[2] = ~pattern20[3];
	assign HEX0[6] = ~pattern20[2];
	assign HEX0[5] = ~pattern20[1];
	assign HEX0[0] = ~pattern20[0];
	assign HEX0[1] = 1'b1;
	assign HEX0[4] = 1'b1;
	

	// Clock generation
	always@(posedge CLOCK_50) begin
		counter = counter + 1;
	end
		
	// Pattern Shifting
	always@(posedge CLOCK) begin
		if (~resetn) begin
			pattern10 = 10'b0;
			pattern20 = 20'b0;
		end
		
		if (shiftleft) begin
			pattern10 = shift1 ^ shift0 ? {pattern10[8:0], shift1} : {pattern10[8:0], pattern10[9]};
			pattern20 = shift1 ^ shift0 ? {pattern20[18:0], shift1} : {pattern20[18:0], pattern20[19]};
		end
		else if (shiftright) begin 
			pattern10 = shift1 ^ shift0 ? {shift1, pattern10[9:1]} : {pattern10[0], pattern10[9:1]};
			pattern20 = shift1 ^ shift0 ? {shift1, pattern20[19:1]} : {pattern20[0], pattern20[19:1]};
		end
		
	end
	
//	always@(negedge doublespeed or negedge halfspeed) begin
//		if (~halfspeed)
//			counter_mask = {counter_mask[24:0],counter_mask[25]};
//		else if (~doublespeed)
//			counter_mask = {counter_mask[0],counter_mask[25:1]};
//	end
		
endmodule
